#ifndef SHARED_OBJECT_H
#define SHARED_OBJECT_H

#include <vector>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
using namespace std;

/* Result that returned to CPU for topK condidate */
struct Result{
	int query;		// query ID
	int feature_id;	// feature ID
	int count;	// accumulate distance
	float lb;			// lower bound 
	float ub;			// upper bound

	__device__ __host__ 
	void print_result_entry(){
		printf("%3d %9d %3d %9.1f %9.1f",this->query,this->feature_id,this->count,this->lb,this->ub);
	}
};

typedef int T;


class SharedObject{
public:
	SharedObject();
	~SharedObject(){};

	// GPU get result in the argument from CPU
	void get_cpu_result(thrust::host_vector<T>& result); 

	// CPU set result for GPU
	void set_cpu_result(vector<T>& input);

	// CPU get result in the argument from GPU
	void get_gpu_result(vector<T>& result);

	// GPU set result for CPU
	void set_gpu_result(thrust::device_vector<T>& result);

private:
	pthread_mutex_t	mutex_cpu_result;
	pthread_mutex_t mutex_gpu_result;

	pthread_cond_t	cpu_result_ready;
	pthread_cond_t	gpu_result_ready;

	bool cpu_ready_indicator;
	bool gpu_ready_indicator;

	vector<T> cpu2gpu;	// result for CPU pass to GPU
	vector<T> gpu2cpu;	// result for GPU pass to CPU
};

#endif